import 'dart:math';

import 'package:flutter/material.dart';

//https://github.com/HitenDev/flutter_effects/blob/master/lib/src/text/line_border_text.dart
class LineBorderText extends StatefulWidget {

  @override
  State<StatefulWidget> createState() => _LineBorderTextState();

}

class _LineBorderTextState extends State<LineBorderText> with TickerProviderStateMixin<LineBorderText>{

  late AnimationController animationController;

  @override
  void initState() {
    super.initState();
    animationController = AnimationController(vsync: this, duration: Duration(milliseconds: 600));
    // animationController.addStatusListener((status) {
    //   if(status == AnimationStatus.completed) {
    //     animationController.value = 0;
    //   }
    // });
    animationController.repeat();
  }

  @override
  void dispose() {
    animationController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: animationController,
      builder: (context, child) {
        double value = animationController.value;
        return CustomPaint(
            size: Size.zero,
            foregroundPainter: _BorderLinePainter(value),
            child: RepaintBoundary(child: innerWidget()));
      },
    );
  }

  innerWidget() => const Padding(
      padding: EdgeInsets.fromLTRB(20, 20, 20, 20),
      child: Text("请稍候",
          style: TextStyle(fontSize: 30, fontWeight: FontWeight.bold)));
}

class _BorderLinePainter extends CustomPainter {

  final double _progress;

  _BorderLinePainter(this._progress);

  @override
  void paint(Canvas canvas, Size size) {
    Paint paint = Paint();
    paint.color = Colors.black;
    paint.isAntiAlias = true;
    paint.style = PaintingStyle.stroke;
    paint.strokeCap = StrokeCap.square;
    paint.strokeWidth = 2;

    double percent = _progress;
    double percent2 = sqrt(3.38 - (percent - 1.7) * (percent - 1.7)) - 0.7;

    double width = size.width;
    double height = size.height;

    Offset pA = const Offset(0, 0);
    Offset pB = Offset(width, 0);
    Offset pC = Offset(width, height);
    Offset pD = Offset(0, height);

    Offset p1 = Offset(width * percent2, pB.dy);
    canvas.drawLine(p1, pB, paint);

    Offset p2 = Offset(pB.dx, height * percent);
    canvas.drawLine(pB, p2, paint);

    Offset p3 = Offset(width, height * percent2);
    canvas.drawLine(p3, pC, paint);

    Offset p4 = Offset(width * (1 - percent), height);
    canvas.drawLine(pC, p4, paint);

    Offset p5 = Offset(width * (1 - percent2), height);
    canvas.drawLine(p5, pD, paint);

    Offset p6 = Offset(0, height * (1 - percent));
    canvas.drawLine(pD, p6, paint);

    Offset p7 = Offset(0, height * (1 - percent2));
    canvas.drawLine(p7, pA, paint);

    Offset p8 = Offset(width * percent, 0);
    canvas.drawLine(pA, p8, paint);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    if (oldDelegate is _BorderLinePainter) {
      double oldProgress = oldDelegate._progress;
      if (oldProgress == _progress) {
        return false;
      }
    }
    return true;
  }
}